library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.custom_types.all;

entity ALU_RCA is
port(
  Clk : in std_logic;
  Reset : in std_logic;
  A : in std_logic_vector(31 downto 0);
  B : in std_logic_vector(31 downto 0);
  Op : in std_logic_vector(3 downto 0);
  Outs : out std_logic_vector(31 downto 0)
);
end ALU_RCA;

architecture rtl of ALU_RCA is

component preCalculatorB is
port(
    B	: in std_logic_vector(31 downto 0);
	Op	: in std_logic_vector(3 downto 0);
    inB	: out std_logic_vector(31 downto 0);
    Cin	: out std_logic
  );
end component;

component preCalculatorA is
port(
    A	: in std_logic_vector(31 downto 0);
	Op	: in std_logic_vector(3 downto 0);
    inA: out std_logic_vector(31 downto 0)
  );
end component;

component RCA is
	port(
	  A   : in std_logic_vector(31 downto 0);
	  B   : in std_logic_vector(31 downto 0);
	  Cin : in std_logic;
	  Sum : out std_logic_vector(31 downto 0);
	  CO  : out std_logic;
	  V   : out std_logic
	);
end component;
component bitwiseAND is
	port(
	  A   : in std_logic_vector(31 downto 0);
	  B   : in std_logic_vector(31 downto 0);
	  C   : out std_logic_vector(31 downto 0)
	);
end component;
component bitwiseOR is
	port(
	  A   : in std_logic_vector(31 downto 0);
	  B   : in std_logic_vector(31 downto 0);
	  C   : out std_logic_vector(31 downto 0)
	);
end component;
component bitwiseNOR is
	port(
	  A   : in std_logic_vector(31 downto 0);
	  B   : in std_logic_vector(31 downto 0);
	  C   : out std_logic_vector(31 downto 0)
	);
end component;
component bitwiseXOR is
	port(
	  A   : in std_logic_vector(31 downto 0);
	  B   : in std_logic_vector(31 downto 0);
	  C   : out std_logic_vector(31 downto 0)
	);
end component;
component shiftLeft is
	port(
	  A   : in std_logic_vector(31 downto 0);
	  B   : in std_logic_vector(31 downto 0);
	  C   : out std_logic_vector(31 downto 0)
	);
	end component;
	component shiftRightLogical is
	port(
	  A   : in std_logic_vector(31 downto 0);
	  B   : in std_logic_vector(31 downto 0);
	  C   : out std_logic_vector(31 downto 0)
	);
	end component;
	component shiftRightArithmetic is
	port(
	  A   : in std_logic_vector(31 downto 0);
	  B   : in std_logic_vector(31 downto 0);
	  C   : out std_logic_vector(31 downto 0)
	);
end component;
component SLTU is
	port(
	  CO  	 : in std_logic;
	  Cout   : out std_logic_vector(31 downto 0)	  
	);
end component;
component SLT is
port(
  MSB  	 : in std_logic;
  V  	 : in std_logic;
  Cout   : out std_logic_vector(31 downto 0)
);
end component;
component Mux16x1 is
	port(
	  
	  Ins 	 	 : in bus16x32;
	  Op		 : in std_logic_vector(3 downto 0);
	  Outs  	 : out std_logic_vector(31 downto 0)
	);
end component;

signal Cin,CO,V		: std_logic;
signal inA,inB,sum	: std_logic_vector(31 downto 0);
signal muxIns 		: bus16x32;
signal muxOuts		: std_logic_vector(31 downto 0);
signal in_pipeline 	: in_pipeline_stage;
signal outBus		: bus16x32;
begin
	rippleAdder0	: RCA 					port map(inA,inB,Cin,sum,CO,V);
	logicAND		: bitwiseAND 			port map(inA,inB,outBus(4));
	logicOR			: bitwiseOR 			port map(inA,inB,outBus(5));
	logicNOR		: bitwiseNOR 			port map(inA,inB,outBus(6));
	logicXOR		: bitwiseXOR 			port map(inA,inB,outBus(7));
	leftshift		: shiftLeft 			port map(inA,inB,outBus(8));
	rightshiftlo	: shiftRightLogical 	port map(inA,inB,outBus(10));
	rightshiftar	: shiftRightArithmetic  port map(inA,inB,outBus(11));
	sltop			: SLT 					port map(sum(31),V,outBus(14));
	sltuop			: SLTU	 				port map(CO,outBus(15));
	muxer			: Mux16x1 				port map(outBus,in_pipeline.Op,muxOuts);
	preCalcA		: preCalculatorA		port map(in_pipeline.A,in_pipeline.Op,inA);
	preCalcB		: preCalculatorB		port map(in_pipeline.B,in_pipeline.Op,inB,Cin);
	
	outBus(0) <= sum;
	outBus(1) <= sum;
	outBus(2) <= sum;
	outBus(3) <= sum;
	outBus(9)  <= (31 downto 0 => '0');
	outBus(12) <= (31 downto 0 => '0');
	outBus(13) <= (31 downto 0 => '0');
	
	seq_process : process (Clk,Reset) is
	begin
		if rising_edge(Clk) and Reset = '1' then
			in_pipeline.A <= A;
			in_pipeline.B <= B;
			in_pipeline.Op <= Op;
			Outs <= muxOuts;
		end if;
	end process seq_process;
end architecture rtl;
---------------------------------------------------------------------------------